#lang racket


(require "../base/main.rkt")

(provide try-exn-connection
         try-void-connection

         list<vector<real>><-list<coord>
         list<coord><-vector<vector<real>>

         real<-number
         scale-matrix<-coord
         
         vector<real><-coord
         vector<real><-list<number>
         vector<real><-list<coord>)


;(define (try-exn-connection msg fn (count 1))
;  (define (try-connection-handler e)
;    (cond ((> count 0)
;           (displayln msg)
;           (sleep 1)
;           (try-exn-connection msg fn (- count 1)))
;          (else
;           (raise e))))
;  (with-handlers ((exn:fail? try-connection-handler))
;    (fn)))

; edit: worst possible hack; change MysterX exceptions
(define exn-re (regexp "code = 80010001"))

(define (try-exn-connection msg fn (count 5))
  (define (try-connection-handler e)
    (cond ((and (regexp-match exn-re (exn-message e)) (> count 0))
           (displayln msg)
           (sleep 1)
           (try-exn-connection msg fn (- count 1)))
          (else
           (raise e))))
  (with-handlers ((exn:fail? try-connection-handler))
    (fn)))

(define (try-void-connection msg fn (count 3))
  (let ((result (fn)))
    (if (void? result)
      (cond ((> count 0)
             (sleep 1)
             (try-void-connection msg fn (- count 1)))
            (else
             (error 'try-void-connection msg)))
	  result)))

(define (list<vector<real>><-list<coord> ps)
  (map vector<real><-coord ps))

(define (list<coord><-vector<vector<real>> v)
  (map coord<-vector (vector->list v)))

(define real<-number exact->inexact)

(define (scale-matrix<-coord p)
  (let ((x (real<-number (xyz-x p)))
        (y (real<-number (xyz-y p)))
        (z (real<-number (xyz-z p))))
    (vector
     (vector  x  0.0 0.0 0.0)
     (vector 0.0  y  0.0 0.0)
     (vector 0.0 0.0  z  0.0)
     (vector 0.0 0.0 0.0 1.0))))

(define (vector<real><-coord p)
  (vector-map real<-number (vector<-coord p)))

(define (vector<real><-list<number> l)
  (list->vector (map real<-number l)))

(define (vector<real><-list<coord> ps)
  (apply vector-append (map vector<real><-coord ps)))